﻿//_________________________________Copyright (c) 2021,LangGe Co.,Ltd_____________________________
//                                       All rights reserved.
// 
//   文件名称：libc.cpp
//   文件标识：见配置管理计划书
//   描    述：字符串操作(跨平台)
// 
//   当前版本：1.0
//   作    者：张小刚整理
//   完成日期：2022.02.08
//_______________________________________________________________________________________________

#include "osapi.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <memory>
#include <string>
#include <codecvt>
#include <locale>
#include <chrono>

#ifdef _MSC_VER
#pragma warning(disable:4996)
#endif // _MSC_VER

/* set bit masks for the possible character types */
#ifdef _UPPER
#undef _UPPER
#endif //_UPPER
#define _UPPER          0x1     /* upper case letter */
#ifdef _LOWER
#undef _LOWER
#endif //_LOWER
#define _LOWER          0x2     /* lower case letter */
#ifdef _DIGIT
#undef _DIGIT
#endif //_DIGIT
#define _DIGIT          0x4     /* digit[0-9] */
#ifdef _SPACE
#undef _SPACE
#endif //_SPACE
#define _SPACE          0x8     /* tab, carriage return, newline, */
/* vertical tab or form feed */
#ifdef _PUNCT
#undef _PUNCT
#endif //_PUNCT
#define _PUNCT          0x10    /* punctuation character */
#ifdef _CONTROL
#undef _CONTROL
#endif //_CONTROL
#define _CONTROL        0x20    /* control character */
#ifdef _BLANK
#undef _BLANK
#endif //_BLANK
#define _BLANK          0x40    /* space char */
#ifdef _HEX
#undef _HEX
#endif //_HEX
#define _HEX            0x80    /* hexadecimal digit */

#ifdef _LEADBYTE
#undef _LEADBYTE
#endif //_LEADBYTE
#define _LEADBYTE       0x8000                  /* multibyte leadbyte */
#ifdef _ALPHA
#undef _ALPHA
#endif //_ALPHA
#define _ALPHA          (0x0100|_UPPER|_LOWER)  /* alphabetic character */

unsigned short os_ctype[256] =
{
    _CONTROL,               /* 00 (NUL) */
    _CONTROL,               /* 01 (SOH) */
    _CONTROL,               /* 02 (STX) */
    _CONTROL,               /* 03 (ETX) */
    _CONTROL,               /* 04 (EOT) */
    _CONTROL,               /* 05 (ENQ) */
    _CONTROL,               /* 06 (ACK) */
    _CONTROL,               /* 07 (BEL) */
    _CONTROL,               /* 08 (BS)  */
    _SPACE + _CONTROL,        /* 09 (HT)  */
    _SPACE + _CONTROL,        /* 0A (LF)  */
    _SPACE + _CONTROL,        /* 0B (VT)  */
    _SPACE + _CONTROL,        /* 0C (FF)  */
    _SPACE + _CONTROL,        /* 0D (CR)  */
    _CONTROL,               /* 0E (SI)  */
    _CONTROL,               /* 0F (SO)  */
    _CONTROL,               /* 10 (DLE) */
    _CONTROL,               /* 11 (DC1) */
    _CONTROL,               /* 12 (DC2) */
    _CONTROL,               /* 13 (DC3) */
    _CONTROL,               /* 14 (DC4) */
    _CONTROL,               /* 15 (NAK) */
    _CONTROL,               /* 16 (SYN) */
    _CONTROL,               /* 17 (ETB) */
    _CONTROL,               /* 18 (CAN) */
    _CONTROL,               /* 19 (EM)  */
    _CONTROL,               /* 1A (SUB) */
    _CONTROL,               /* 1B (ESC) */
    _CONTROL,               /* 1C (FS)  */
    _CONTROL,               /* 1D (GS)  */
    _CONTROL,               /* 1E (RS)  */
    _CONTROL,               /* 1F (US)  */
    _SPACE + _BLANK,          /* 20 SPACE */
    _PUNCT,                 /* 21 !     */
    _PUNCT,                 /* 22 "     */
    _PUNCT,                 /* 23 #     */
    _PUNCT,                 /* 24 $     */
    _PUNCT,                 /* 25 %     */
    _PUNCT,                 /* 26 &     */
    _PUNCT,                 /* 27 '     */
    _PUNCT,                 /* 28 (     */
    _PUNCT,                 /* 29 )     */
    _PUNCT,                 /* 2A *     */
    _PUNCT,                 /* 2B +     */
    _PUNCT,                 /* 2C ,     */
    _PUNCT,                 /* 2D -     */
    _PUNCT,                 /* 2E .     */
    _PUNCT,                 /* 2F /     */
    _DIGIT + _HEX,            /* 30 0     */
    _DIGIT + _HEX,            /* 31 1     */
    _DIGIT + _HEX,            /* 32 2     */
    _DIGIT + _HEX,            /* 33 3     */
    _DIGIT + _HEX,            /* 34 4     */
    _DIGIT + _HEX,            /* 35 5     */
    _DIGIT + _HEX,            /* 36 6     */
    _DIGIT + _HEX,            /* 37 7     */
    _DIGIT + _HEX,            /* 38 8     */
    _DIGIT + _HEX,            /* 39 9     */
    _PUNCT,                 /* 3A :     */
    _PUNCT,                 /* 3B ;     */
    _PUNCT,                 /* 3C <     */
    _PUNCT,                 /* 3D =     */
    _PUNCT,                 /* 3E >     */
    _PUNCT,                 /* 3F ?     */
    _PUNCT,                 /* 40 @     */
    _UPPER + _HEX,            /* 41 A     */
    _UPPER + _HEX,            /* 42 B     */
    _UPPER + _HEX,            /* 43 C     */
    _UPPER + _HEX,            /* 44 D     */
    _UPPER + _HEX,            /* 45 E     */
    _UPPER + _HEX,            /* 46 F     */
    _UPPER,                 /* 47 G     */
    _UPPER,                 /* 48 H     */
    _UPPER,                 /* 49 I     */
    _UPPER,                 /* 4A J     */
    _UPPER,                 /* 4B K     */
    _UPPER,                 /* 4C L     */
    _UPPER,                 /* 4D M     */
    _UPPER,                 /* 4E N     */
    _UPPER,                 /* 4F O     */
    _UPPER,                 /* 50 P     */
    _UPPER,                 /* 51 Q     */
    _UPPER,                 /* 52 R     */
    _UPPER,                 /* 53 S     */
    _UPPER,                 /* 54 T     */
    _UPPER,                 /* 55 U     */
    _UPPER,                 /* 56 V     */
    _UPPER,                 /* 57 W     */
    _UPPER,                 /* 58 X     */
    _UPPER,                 /* 59 Y     */
    _UPPER,                 /* 5A Z     */
    _PUNCT,                 /* 5B [     */
    _PUNCT,                 /* 5C \     */
    _PUNCT,                 /* 5D ]     */
    _PUNCT,                 /* 5E ^     */
    _PUNCT,                 /* 5F _     */
    _PUNCT,                 /* 60 `     */
    _LOWER + _HEX,            /* 61 a     */
    _LOWER + _HEX,            /* 62 b     */
    _LOWER + _HEX,            /* 63 c     */
    _LOWER + _HEX,            /* 64 d     */
    _LOWER + _HEX,            /* 65 e     */
    _LOWER + _HEX,            /* 66 f     */
    _LOWER,                 /* 67 g     */
    _LOWER,                 /* 68 h     */
    _LOWER,                 /* 69 i     */
    _LOWER,                 /* 6A j     */
    _LOWER,                 /* 6B k     */
    _LOWER,                 /* 6C l     */
    _LOWER,                 /* 6D m     */
    _LOWER,                 /* 6E n     */
    _LOWER,                 /* 6F o     */
    _LOWER,                 /* 70 p     */
    _LOWER,                 /* 71 q     */
    _LOWER,                 /* 72 r     */
    _LOWER,                 /* 73 s     */
    _LOWER,                 /* 74 t     */
    _LOWER,                 /* 75 u     */
    _LOWER,                 /* 76 v     */
    _LOWER,                 /* 77 w     */
    _LOWER,                 /* 78 x     */
    _LOWER,                 /* 79 y     */
    _LOWER,                 /* 7A z     */
    _PUNCT,                 /* 7B {     */
    _PUNCT,                 /* 7C |     */
    _PUNCT,                 /* 7D }     */
    _PUNCT,                 /* 7E ~     */
    _CONTROL,               /* 7F (DEL) */
    /* and the rest are 0... */
};

/**
 * @brief 格式化字符串
 * @param buf       缓冲区，用来存储格式化后的结果
 * @param size      缓冲区尺寸
 * @param format    格式控制字符串
 * @param ...       格式控制参数
 * @return 如果格式化后的字符串长度小于 size，则会把字符串全部复制到 str 中，并给其后添加一个字符串结束符 \0；
 *         如果格式化后的字符串长度大于等于 size，超过 size 的部分会被截断，只将其中的 (size-1) 个字符复制到 
 *         str 中，并给其后添加一个字符串结束符 \0，返回值为欲写入的字符串长度。
 * @note   编码格式 UTF-8
 */
int32_t ossnprintf(char *buf,const int32_t size,const char *format,...)
{
	if (nullptr==buf||size<=0||nullptr==format)
	{
		return 0;
	}

	va_list arglist;
	va_start(arglist, format);
	const int32_t ret = vsnprintf(buf, size, format,arglist);
	va_end(arglist);

	return ret;
}

/**
 * @brief 格式化字符串
 * @param buf       缓冲区，用来存储格式化后的结果
 * @param count     缓冲区尺寸（元素个数，并非字节尺寸）
 * @param format    格式控制字符串
 * @param ...       格式控制参数
 * @return 如果格式化后的字符串长度小于 size，则会把字符串全部复制到 str 中，并给其后添加一个字符串结束符 \0；
 *         如果格式化后的字符串长度大于等于 size，超过 size 的部分会被截断，只将其中的 (size-1) 个字符复制到 
 *         str 中，并给其后添加一个字符串结束符 \0，返回值为欲写入的字符串长度。
 * @note  编码格式 UTF-16
 */
int32_t ossnprintf(char16_t *buf,const int32_t count,const char *format,...)
{
	if (nullptr==buf||count<=0||nullptr==format)
	{
		return 0;
	}

	std::unique_ptr<char[]> c8Buf(new(std::nothrow) char[count]);
	if(nullptr==c8Buf.get())
	{
		return 0;
	}
	memset(c8Buf.get(),0,sizeof(char)*count);

	va_list arglist;
	va_start(arglist, format);
	const int32_t ret=vsnprintf(c8Buf.get(),count,format,arglist);
	va_end(arglist);
	if (ret<=0)
	{
		return 0;
	}

	return osConvertToUTF16(c8Buf.get(),buf,count);
}

/**
 * @brief 格式化字符串
 * @param buf       缓冲区，用来存储格式化后的结果
 * @param count     缓冲区尺寸（元素个数，并非字节尺寸）
 * @param format    格式控制字符串
 * @param ...       格式控制参数
 * @return 如果格式化后的字符串长度小于 size，则会把字符串全部复制到 str 中，并给其后添加一个字符串结束符 \0；
 *         如果格式化后的字符串长度大于等于 size，超过 size 的部分会被截断，只将其中的 (size-1) 个字符复制到 
 *         str 中，并给其后添加一个字符串结束符 \0，返回值为欲写入的字符串长度。
 * @note  编码格式 UTF-16
 */
int32_t ossnprintf(char32_t *buf,const int32_t count,const char *format,...)
{
	if (nullptr==buf||count<=0||nullptr==format)
	{
		return 0;
	}

	std::unique_ptr<char[]> c8Buf(new(std::nothrow) char[count]);
	if(nullptr==c8Buf.get())
	{
		return 0;
	}
	memset(c8Buf.get(),0,sizeof(char)*count);

	va_list arglist;
	va_start(arglist, format);
	int32_t ret=vsnprintf(c8Buf.get(),count,format,arglist);
	va_end(arglist);
	if (ret<=0)
	{
		return 0;
	}

	return osConvertToUTF32(c8Buf.get(),buf,count);
}

/**
 * @brief 计算指定字符串长度
 * @param str  指定字符串
 * @return 返回指定字符串长度
 */
int32_t osstrlen(const char *str)
{
	if(nullptr==str)
	{
		return 0;
	}
	const char *ptr=str;
	while(*ptr)
		++ptr;
	return int32_t(ptr-str);
}

/**
 * @brief 计算指定字符串长度
 * @param str  指定字符串
 * @return 返回指定字符串长度
 */
int32_t osstrlen(const char16_t *str)
{
	if(nullptr==str)
	{
		return 0;
	}
	const char16_t *ptr=str;
	while(*ptr)
		++ptr;
	return int32_t(ptr-str);
}

/**
 * @brief 计算指定字符串长度
 * @param str  指定字符串
 * @return 返回指定字符串长度
 */
int32_t osstrlen(const char32_t *str)
{
	if(nullptr==str)
	{
		return 0;
	}
	const char32_t *ptr=str;
	while(*ptr)
		++ptr;
	return int32_t(ptr-str);
}

/**
 * @brief 实现字符串拷贝
 * @param dest  字符串存储区域
 * @param src   待拷贝字符串
 * @return 返回字符串存储区域地址
 */
char *osstrcpy(char *dest,const char *src)
{
	if(nullptr==dest||nullptr==src)
	{
		return dest;
	}
	char *saveddest=dest;
	while(*src)
		*dest++=*src++;
	*dest=0;
	return saveddest;
}

/**
 * @brief 实现字符串拷贝
 * @param dest  字符串存储区域
 * @param src   待拷贝字符串
 * @return 返回字符串存储区域地址
 * @note 编码格式 UTF-16
 */
char16_t *osstrcpy(char16_t *dest,const char16_t *src)
{
	if(nullptr==dest||nullptr==src)
	{
		return dest;
	}
	char16_t *saveddest=dest;
	while(*src)
		*dest++=*src++;
	*dest=0;
	return saveddest;
}

/**
 * @brief 实现字符串拷贝
 * @param dest  字符串存储区域
 * @param src   待拷贝字符串
 * @return 返回字符串存储区域地址
 * @note 编码格式 UTF-32
 */
char32_t *osstrcpy(char32_t *dest,const char32_t *src)
{
	if(nullptr==dest||nullptr==src)
	{
		return dest;
	}
	char32_t *saveddest=dest;
	while(*src)
		*dest++=*src++;
	*dest=0;
	return saveddest;
}

/**
 * @brief 实现字符串拼接
 * @param dest  待拼接字符串（此存储区需要足够大，能够容纳拼接后字符串）
 * @param src   待拼接字符串
 * @return 返回拼接后字符串指针
 * @note 编码格式 UTF-8
 */
char *osstrcat(char *dest, const char *src)
{
	if (nullptr==dest||nullptr==src)
	{
		return dest;
	}

	char *saveddest=dest;
	const int32_t len=osstrlen(dest);
	osstrcpy(dest+len,src);

	return saveddest;
}

/**
 * @brief 实现字符串拼接
 * @param dest  待拼接字符串（此存储区需要足够大，能够容纳拼接后字符串）
 * @param src   待拼接字符串
 * @return 返回拼接后字符串指针
 * @note 编码格式 UTF-16
 */
char16_t *osstrcat(char16_t *dest,const char16_t *src)
{
	if (nullptr==dest||nullptr==src)
	{
		return dest;
	}

	char16_t *saveddest=dest;
	const int32_t len=osstrlen(dest);
	osstrcpy(dest+len,src);

	return saveddest;
}

/**
 * @brief 实现字符串拼接
 * @param dest  待拼接字符串（此存储区需要足够大，能够容纳拼接后字符串）
 * @param src   待拼接字符串
 * @return 返回拼接后字符串指针
 * @note 编码格式 UTF-32
 */
char32_t *osstrcat(char32_t *dest,const char32_t *src)
{
	if (nullptr==dest||nullptr==src)
	{
		return dest;
	}

	char32_t *saveddest=dest;
	const int32_t len=osstrlen(dest);
	osstrcpy(dest+len,src);

	return saveddest;
}

/**
 * @brief 实现字符串中查找指定字符功能
 * @param str  字符串
 * @param ch   指定字符
 * @return 返回字符串中，指向指定字符的指针
 * @note 编码格式 UTF-8
 */
char *osstrchr(const char *str,const char ch)
{
	if (nullptr==str)
	{
		return nullptr;
	}

	char *ptr=(char*)str;
	while(*ptr)
	{
		if(*ptr==ch)
		{
			return ptr;
		}
		++ptr;
	}

	return nullptr;
}

/**
 * @brief 实现字符串中查找指定字符功能
 * @param str  字符串
 * @param ch   指定字符
 * @return 返回字符串中，指向指定字符的指针
 * @note 编码格式 UTF-16
 */
char16_t *osstrchr(const char16_t *str,const char16_t ch)
{
	if (nullptr==str)
	{
		return nullptr;
	}

	char16_t *ptr=(char16_t*)str;
	while(*ptr)
	{
		if(*ptr==ch)
		{
			return ptr;
		}
		++ptr;
	}

	return nullptr;
}

/**
 * @brief 实现字符串中查找指定字符功能
 * @param str  字符串
 * @param ch   指定字符
 * @return 返回字符串中，指向指定字符的指针
 * @note 编码格式 UTF-32
 */
char32_t *osstrchr(const char32_t *str,const char32_t ch)
{
	if (nullptr==str)
	{
		return nullptr;
	}

	char32_t *ptr=(char32_t*)str;
	while(*ptr)
	{
		if(*ptr==ch)
		{
			return ptr;
		}
		++ptr;
	}

	return nullptr;
}

/**
 * @brief 在字符串str1中查找第一次出现子字符串str2的位置
 * @param str1   字符串
 * @param str2   子字符串
 * @return 该函数返回在str1中第一次出现str2字符串的位置，如果未找到则返回nullptr
 * @note 编码格式 UTF-8
 */
char *osstrstr(const char *str1,const char *str2)
{
	if (nullptr==str1||nullptr==str2)
	{
		return nullptr;
	}

	char *cp=(char*)str1;
	char *s1=nullptr,*s2=nullptr;

    if (!*str2)
	{
		return((char *)str1);
	}

    while (*cp)
    {
        s1=cp;
        s2=(char *)str2;

        while(*s1&&*s2&&!(*s1-*s2))
            s1++,s2++;

        if (!*s2)
            return(cp);

        cp++;
    }

    return nullptr;
}

/**
 * @brief 在字符串str1中查找第一次出现子字符串str2的位置
 * @param str1   字符串
 * @param str2   子字符串
 * @return 该函数返回在str1中第一次出现str2字符串的位置，如果未找到则返回nullptr。
 * @note 编码格式 UTF-16
 */
char16_t *osstrstr(const char16_t *str1,const char16_t *str2)
{
	if (nullptr==str1||nullptr==str2)
	{
		return nullptr;
	}

	char16_t *cp=(char16_t*)str1;
	char16_t *s1=nullptr,*s2=nullptr;

    if (!*str2)
	{
		return((char16_t*)str1);
	}

    while (*cp)
    {
        s1=cp;
        s2=(char16_t*)str2;

        while(*s1&&*s2&&!(*s1-*s2))
            s1++,s2++;

        if (!*s2)
            return(cp);

        cp++;
    }

    return nullptr;
}

/**
 * @brief 在字符串str1中查找第一次出现子字符串str2的位置
 * @param str1   字符串
 * @param str2   子字符串
 * @return 该函数返回在str1中第一次出现str2字符串的位置，如果未找到则返回nullptr。
 * @note 编码格式 UTF-32
 */
char32_t *osstrstr(const char32_t *str1,const char32_t *str2)
{
	if (nullptr==str1||nullptr==str2)
	{
		return nullptr;
	}

	char32_t *cp=(char32_t*)str1;
	char32_t *s1=nullptr,*s2=nullptr;

    if (!*str2)
	{
		return((char32_t*)str1);
	}

    while (*cp)
    {
        s1=cp;
        s2=(char32_t*)str2;

        while(*s1&&*s2&&!(*s1-*s2))
            s1++,s2++;

        if (!*s2)
            return(cp);

        cp++;
    }

    return nullptr;
}

/**
 * @brief 把s1所指向的字符串和s2所指向的字符串进行比较
 * @param s1   要进行比较的第一个字符串
 * @param s2   要进行比较的第二个字符串
 * @return 如果返回值小于 0，则表示 s1小于s2。 
 * @return 如果返回值大于 0，则表示 s1大于s2。 
 * @return 如果返回值等于 0，则表示 s1等于s2。 
 * @note 编码格式 UTF-8
 */
int32_t osstrcmp(const char *s1,const char *s2)
{
	if (nullptr==s1 && nullptr==s2)
	{
		return 0;
	}
	else if (nullptr==s1)
	{
		return -1;
	}
	else if (nullptr==s2)
	{
		return 1;
	}

	int32_t ret=*(unsigned char*)s1-*(unsigned char*)s2;

    while(!ret&&*s2)
	{ 
		++s1,++s2;
		ret=*(unsigned char*)s1-*(unsigned char*)s2;
	}

    if (ret<0)
        ret=-1;
    else if (ret>0)
        ret=1;

    return ret;	
}

/**
 * @brief 把s1所指向的字符串和s2所指向的字符串进行比较
 * @param s1   要进行比较的第一个字符串
 * @param s2   要进行比较的第二个字符串
 * @return 如果返回值小于 0，则表示 s1小于s2。 
 * @return 如果返回值大于 0，则表示 s1大于s2。 
 * @return 如果返回值等于 0，则表示 s1等于s2。 
 * @note 编码格式 UTF-16
 */
int32_t osstrcmp(const char16_t *s1,const char16_t *s2)
{
	if(nullptr==s1&&nullptr==s2)
	{
		return 0;
	}
	else if(nullptr==s1)
	{
		return -1;
	}
	else if(nullptr==s2)
	{
		return 1;
	}

	int32_t ret=*s1-*s2;

    while(!ret&&*s2)
	{ 
		++s1,++s2;
		ret=*s1-*s2;
	}

    if (ret<0)
        ret=-1;
    else if (ret>0)
        ret=1;

    return ret;	
}

/**
 * @brief 把s1所指向的字符串和s2所指向的字符串进行比较
 * @param s1   要进行比较的第一个字符串
 * @param s2   要进行比较的第二个字符串
 * @return 如果返回值小于 0，则表示 s1小于s2。 
 * @return 如果返回值大于 0，则表示 s1大于s2。 
 * @return 如果返回值等于 0，则表示 s1等于s2。 
 * @note 编码格式 UTF-32
 */
int32_t osstrcmp(const char32_t *s1,const char32_t *s2)
{
	if(nullptr==s1&&nullptr==s2)
	{
		return 0;
	}
	else if(nullptr==s1)
	{
		return -1;
	}
	else if(nullptr==s2)
	{
		return 1;
	}

	int32_t ret=*s1-*s2;

    while(!ret&&*s2)
	{ 
		++s1,++s2;
		ret=*s1-*s2;
	}

    if (ret<0)
        ret=-1;
    else if (ret>0)
        ret=1;

    return ret;	
}

/**
 * @brief 把s1所指向的字符串和s2所指向的字符串进行比较（不区分大小写）
 * @param s1   要进行比较的第一个字符串
 * @param s2   要进行比较的第二个字符串
 * @return 如果返回值小于 0，则表示 s1小于s2。 
 * @return 如果返回值大于 0，则表示 s1大于s2。 
 * @return 如果返回值等于 0，则表示 s1等于s2。 
 * @note 编码格式 UTF-8
 */
int32_t osstricmp(const char *s1,const char *s2)
{
	if(nullptr==s1&&nullptr==s2)
	{
		return 0;
	}
	else if(nullptr==s1)
	{
		return -1;
	}
	else if(nullptr==s2)
	{
		return 1;
	}

	while(*s1!=0&&*s2!=0&&ostolower(*s1)==ostolower(*s2))
	{
		++s1;
		++s2;
	}

	int32_t ls1=ostolower(*s1);
	int32_t ls2=ostolower(*s2);

	if (ls1==ls2) 
		return 0;
	if (ls1<ls2)
		return -1;
	if (ls1>ls2)
		return 1;

	return 0;
}

/**
 * @brief 把s1所指向的字符串和s2所指向的字符串进行比较（不区分大小写）
 * @param s1   要进行比较的第一个字符串
 * @param s2   要进行比较的第二个字符串
 * @return 如果返回值小于 0，则表示 s1小于s2。 
 * @return 如果返回值大于 0，则表示 s1大于s2。 
 * @return 如果返回值等于 0，则表示 s1等于s2。 
 * @note 编码格式 UTF-16
 */
int32_t osstricmp(const char16_t *s1,const char16_t *s2)
{
	if(nullptr==s1&&nullptr==s2)
	{
		return 0;
	}
	else if(nullptr==s1)
	{
		return -1;
	}
	else if(nullptr==s2)
	{
		return 1;
	}

	while(*s1!=0&&*s2!=0&&ostolower(*s1)==ostolower(*s2))
	{
		++s1;
		++s2;
	}

	int32_t ls1=ostolower(*s1);
	int32_t ls2=ostolower(*s2);

	if (ls1==ls2) 
		return 0;
	if (ls1<ls2)
		return -1;
	if (ls1>ls2)
		return 1;

	return 0;
}

/**
 * @brief 把s1所指向的字符串和s2所指向的字符串进行比较（不区分大小写）
 * @param s1   要进行比较的第一个字符串
 * @param s2   要进行比较的第二个字符串
 * @return 如果返回值小于 0，则表示 s1小于s2。 
 * @return 如果返回值大于 0，则表示 s1大于s2。 
 * @return 如果返回值等于 0，则表示 s1等于s2。 
 * @note 编码格式 UTF-32
 */
int32_t osstricmp(const char32_t *s1,const char32_t *s2)
{
	if(nullptr==s1&&nullptr==s2)
	{
		return 0;
	}
	else if(nullptr==s1)
	{
		return -1;
	}
	else if(nullptr==s2)
	{
		return 1;
	}

	while(*s1!=0&&*s2!=0&&ostolower(*s1)==ostolower(*s2))
	{
		++s1;
		++s2;
	}

	int32_t ls1=ostolower(*s1);
	int32_t ls2=ostolower(*s2);

	if (ls1==ls2) 
		return 0;
	if (ls1<ls2)
		return -1;
	if (ls1>ls2)
		return 1;

	return 0;	
}

/**
 * @brief 把str1和str2进行比较，最多比较前num个字节。
 * @param str1    要进行比较的第一个字符串。
 * @param str2    要进行比较的第二个字符串。
 * @param num     要比较的最大字符数。
 * @return 如果返回值小于 0，则表示 str1小于str2。 
 * @return 如果返回值大于 0，则表示 str1大于str2。 
 * @return 如果返回值等于 0，则表示 str1等于str2。
 * @note 编码格式 UTF-8
 */
int32_t osstrincmp(const char *str1,const char *str2,const int32_t num)
{
	if(nullptr==str1&&nullptr==str2)
	{
		return 0;
	}
	else if(nullptr==str1)
	{
		return -1;
	}
	else if(nullptr==str2)
	{
		return 1;
	}

	char c1=0,c2=0;
	for(int32_t ni=0;*str1&&*str2;str1++,str2++)
	{
		c1=*str1;
		c2=*str2;
		if(c1>='a'&&c1<='z'){c1-='a';c1+='A';}
		if(c2>='a'&&c2<='z'){c2-='a';c2+='A';}
		if(c1!=c2) return (int32_t)c1-(int32_t)c2;
		if(++ni>=num) return 0;
	}
	return (int32_t)*str1-(int32_t)*str2;
}

/**
 * @brief 把str1和str2进行比较，最多比较前num个字节。
 * @param str1    要进行比较的第一个字符串。
 * @param str2    要进行比较的第二个字符串。
 * @param num     要比较的最大字符数。
 * @return 如果返回值小于 0，则表示 str1小于str2。 
 * @return 如果返回值大于 0，则表示 str1大于str2。 
 * @return 如果返回值等于 0，则表示 str1等于str2。
 * @note 编码格式 UTF-16
 */
int32_t osstrincmp(const char16_t *str1,const char16_t *str2,const int32_t num)
{
	if(nullptr==str1&&nullptr==str2)
	{
		return 0;
	}
	else if(nullptr==str1)
	{
		return -1;
	}
	else if(nullptr==str2)
	{
		return 1;
	}
	
	char16_t c1=0,c2=0;
	for(int32_t ni=0;*str1&&*str2;str1++,str2++)
	{
		c1=*str1;
		c2=*str2;
		if(c1>=u'a'&&c1<=u'z'){c1-=u'a';c1+=u'A';}
		if(c2>=u'a'&&c2<=u'z'){c2-=u'a';c2+=u'A';}
		if(c1!=c2) return (int32_t)c1-(int32_t)c2;
		if(++ni>=num) return 0;
	}
	return (int32_t)*str1-(int32_t)*str2;
}

/**
 * @brief 把str1和str2进行比较，最多比较前num个字节。
 * @param str1    要进行比较的第一个字符串。
 * @param str2    要进行比较的第二个字符串。
 * @param num     要比较的最大字符数。
 * @return 如果返回值小于 0，则表示 str1小于str2。 
 * @return 如果返回值大于 0，则表示 str1大于str2。 
 * @return 如果返回值等于 0，则表示 str1等于str2。
 * @note 编码格式 UTF-32
 */
int32_t osstrincmp(const char32_t *str1,const char32_t *str2,const int32_t num)
{
	if(nullptr==str1&&nullptr==str2)
	{
		return 0;
	}
	else if(nullptr==str1)
	{
		return -1;
	}
	else if(nullptr==str2)
	{
		return 1;
	}

	char32_t c1=0,c2=0;
	for(int32_t ni=0;*str1&&*str2;str1++,str2++)
	{
		c1=*str1;
		c2=*str2;
		if(c1>=U'a'&&c1<=U'z'){c1-=U'a';c1+=U'A';}
		if(c2>=U'a'&&c2<=U'z'){c2-=U'a';c2+=U'A';}
		if(c1!=c2) return (int32_t)c1-(int32_t)c2;
		if(++ni>=num) return 0;
	}
	return (int32_t)*str1-(int32_t)*str2;
}

/**
 * @brief 将指定英文字母转为小写英文字母
 * @param c 指定英文字母
 * @return 返回转换后的英文字符
 * @note 编码格式 UTF-8
 * @note for faster implementations, this functions can be a table search
 */
char ostolower(const char c)
{
	if (c>='A' && c<='Z')
		return c-'A'+'a';
	else
		return c;
}

/**
 * @brief 将指定英文字母转为小写英文字母
 * @param c 指定英文字母
 * @return 返回转换后的英文字符
 * @note 编码格式 UTF-16
 * @note for faster implementations, this functions can be a table search
 */
char16_t ostolower(const char16_t c)
{
	if(c>=u'A'&&c<=u'Z')
	{
		return c-u'A'+u'a';
	}
	else
	{
		return c;
	}
}

/**
 * @brief 将指定英文字母转为小写英文字母
 * @param c 指定英文字母
 * @return 返回转换后的英文字符
 * @note 编码格式 UTF-32
 * @note for faster implementations, this functions can be a table search
 */
char32_t ostolower(const char32_t c)
{
	if(c>=U'A'&&c<=U'Z')
	{
		return c-U'A'+U'a';
	}
	else
	{
		return c;
	}
}

/**
 * @brief 复制字符串
 * @param str 待赋值字符串
 * @return 返回一字符串指针，该指针指向复制后的新字符串地址。
 *         若返回nullptr表示内存不足。
 * @note 编码格式：UTF-8
 */
char *osstrdup(const char *str)
{
	char *s=(char *)malloc((osstrlen(str)+1)*sizeof(char));
	osstrcpy(s,str);
	return s;
}

/**
 * @brief 复制字符串
 * @param str 待赋值字符串
 * @return 返回一字符串指针，该指针指向复制后的新字符串地址。
 *         若返回nullptr表示内存不足。
 * @note 编码格式 UTF-16
 */
char16_t *osstrdup(const char16_t *str)
{
	char16_t *s=(char16_t*)malloc((osstrlen(str)+1)*sizeof(char16_t));
	osstrcpy(s,str);
	return s;
}

/**
 * @brief 复制字符串
 * @param str 待赋值字符串
 * @return 返回一字符串指针，该指针指向复制后的新字符串地址。
 *         若返回nullptr表示内存不足。
 * @note 编码格式 UTF-32
 */
char32_t *osstrdup(const char32_t *str)
{
	char32_t *s=(char32_t*)malloc((osstrlen(str)+1)*sizeof(char32_t));
	osstrcpy(s,str);
	return s;
}

/**
 * @brief 从字符串读取格式化输入
 * @param buf       待检索字符串
 * @param format    格式化字符串
 * @param ...       可变参数，用于返回格式化字符串表示内容
 * @return 如果成功，该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误，则返回 EOF。
 * @note 编码格式 UTF-8
 */
int32_t ossscanf(const char *buf, const char *format, ...)
{
	if(nullptr==buf||nullptr==format)
	{
		return 0;
	}
	
	va_list arglist;
	va_start(arglist,format);
	const int32_t ret=vsscanf(buf,format,arglist);
	va_end(arglist);

	return ret;
}

/**
 * @brief 从字符串读取格式化输入
 * @param buf       待检索字符串
 * @param format    格式化字符串
 * @param ...       可变参数，用于返回格式化字符串表示内容
 * @return 如果成功，该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误，则返回 EOF。
 * @note 编码格式 UTF-16
 */
int32_t ossscanf(const char16_t *buf,const char16_t *format,...)
{
	if (nullptr==buf||nullptr==format)
	{
		return 0;
	}

	const int32_t buf_count=4*(osstrlen(buf)+1);
	std::unique_ptr<char[]> u8_buf(new(std::nothrow) char[buf_count]);
	if(nullptr==u8_buf)
	{
		return 0;
	}
	memset(u8_buf.get(),0,buf_count*sizeof(char));
	const int32_t format_count=4*(osstrlen(format)+1);
	std::unique_ptr<char[]> u8_format(new(std::nothrow) char[format_count]);
	if(nullptr==u8_format)
	{
		return 0;
	}
	memset(u8_format.get(),0,format_count*sizeof(char));

	int32_t ret=osConvertToUTF8(buf,u8_buf.get(),buf_count);
	if (ret<=0)
	{
		return 0;
	}
	ret=osConvertToUTF8(format,u8_format.get(),format_count);
	if (ret<=0)
	{
		return 0;
	}

	va_list arglist;
	va_start(arglist,format);
	ret=vsscanf(u8_buf.get(),u8_format.get(),arglist);
	va_end(arglist);

	return ret;
}

/**
 * @brief 从字符串读取格式化输入
 * @param buf       待检索字符串
 * @param format    格式化字符串
 * @param ...       可变参数，用于返回格式化字符串表示内容
 * @return 如果成功，该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误，则返回 EOF。
 * @note 编码格式 UTF-32
 */
int32_t ossscanf(const char32_t *buf,const char32_t *format,...)
{
	if (nullptr==buf||nullptr==format)
	{
		return 0;
	}

	const int32_t buf_count=4*(osstrlen(buf)+1);
	std::unique_ptr<char[]> u8_buf(new(std::nothrow) char[buf_count]);
	if(nullptr==u8_buf)
	{
		return 0;
	}
	memset(u8_buf.get(),0,buf_count*sizeof(char));
	const int32_t format_count=4*(osstrlen(format)+1);
	std::unique_ptr<char[]> u8_format(new(std::nothrow) char[format_count]);
	if(nullptr==u8_format)
	{
		return 0;
	}
	memset(u8_format.get(),0,format_count*sizeof(char));

	int32_t ret=osConvertToUTF8(buf,u8_buf.get(),buf_count);
	if (ret<=0)
	{
		return 0;
	}
	ret=osConvertToUTF8(format,u8_format.get(),format_count);
	if (ret<=0)
	{
		return 0;
	}

	va_list arglist;
	va_start(arglist,format);
	ret=vsscanf(u8_buf.get(),u8_format.get(),arglist);
	va_end(arglist);

	return ret;
}

/**
 * @brief 检测一个字符是否是空白符
 *        空白符包括：'' '\t' '\n' '\v' '\f' '\r'
 * @param c 待检测字符
 * @return 返回值为非零（真）表示c是空白符，返回值为零（假）表示c不是空白符
 * @note 此函数同时支持UTF-8、UTF-16以及UTF-32编码格式字符
 */
int32_t osisspace(const int32_t c)
{
	if (c < 0 || c > 255)
		return 0;
	else
		return (os_ctype[c] & _SPACE);
}

/**
 * @brief 检测一个字符是否是十进制数字
 * @param c   要检测的字符
 * @return 返回值为非零（真）表示c是十进制数字，返回值为零（假）表示c不是十进制数字
 * @note 此函数同时支持UTF-8、UTF-16以及UTF-32编码格式字符
 */
int32_t osisdigit(const int32_t c)
{
	if (c < 0 || c > 255)
		return 0;
	else
		return (os_ctype[c] & _DIGIT);
}

/**
 * @brief 把参数 str 所指向的字符串转换为一个整数（类型为 int32_t 型）。
 * @param nptr     要转换为整数的字符串。
 * @return 该函数返回转换后的长整数，如果没有执行有效的转换，则返回零。
 */
int32_t osatoi(const char *nptr)
{
    int32_t c=0;              /* current char */
    int32_t total=0;          /* current total */
    int32_t sign=0;           /* if '-', then negative, otherwise positive */

    /* skip whitespace */
    while (osisspace((int32_t)(unsigned char)*nptr))
        ++nptr;

    c = (int32_t)(unsigned char) *nptr++;
    sign = c;           /* save sign indication */
    if (c == '-' || c == '+')
        c = (int32_t)(unsigned char) *nptr++;    /* skip sign */

    total = 0;

    while (osisdigit(c))
    {
        total = 10 * total + (c - '0');     /* accumulate digit */
        c = (int32_t)(unsigned char) *nptr++;    /* get next char */
    }

    if (sign == '-')
        return -total;
    else
        return total;   /* return result, negated if necessary */
}

/**
 * @brief 把参数 str 所指向的字符串转换为一个整数（类型为 int32_t 型）。
 * @param nptr     要转换为整数的字符串。
 * @return 该函数返回转换后的长整数，如果没有执行有效的转换，则返回零。
 * @note 编码格式 UTF-16
 */
int32_t osatoi(const char16_t *nptr)
{
	int32_t c=0;              /* current char */
    int32_t total=0;          /* current total */
    int32_t sign=0;           /* if '-', then negative, otherwise positive */

    /* skip whitespace */
    while (osisspace((int32_t)*nptr))
        ++nptr;

    c = (int32_t)*nptr++;
    sign = c;           /* save sign indication */
    if (c == u'-' || c == u'+')
        c = (int32_t)*nptr++;    /* skip sign */

    total = 0;

    while (osisdigit(c))
    {
        total = 10 * total + (c - u'0');     /* accumulate digit */
        c = (int32_t)*nptr++;    /* get next char */
    }
	
    if (sign == u'-')
        return -total;
    else
        return total;   /* return result, negated if necessary */
}

/**
 * @brief 把参数 str 所指向的字符串转换为一个整数（类型为 int32_t 型）。
 * @param nptr     要转换为整数的字符串。
 * @return 该函数返回转换后的长整数，如果没有执行有效的转换，则返回零。
 * @note 编码格式 UTF-32
 */
int32_t osatoi(const char32_t *nptr)
{
	int32_t c=0;              /* current char */
    int32_t total=0;          /* current total */
    int32_t sign=0;           /* if '-', then negative, otherwise positive */

    /* skip whitespace */
    while (osisspace((int32_t)*nptr))
        ++nptr;

    c = (int32_t)*nptr++;
    sign = c;           /* save sign indication */
    if (c == U'-' || c == U'+')
        c = (int32_t) *nptr++;    /* skip sign */

    total = 0;

    while (osisdigit(c))
    {
        total = 10 * total + (c - U'0');     /* accumulate digit */
        c = (int32_t)*nptr++;    /* get next char */
    }
	
    if (sign == U'-')
        return -total;
    else
        return total;   /* return result, negated if necessary */
}

/**
 * @brief 用于把整数转换成字符串
 * @param value     为要转换为字符的数字
 * @param str       为转换后的指向字符串的指针
 * @param radix     为转换数字的进制数
 * @return 返回指向转换后的字符串指针
 * @note 编码格式 UTF-8 
 */
char *ositoa(int32_t value,char *str,int32_t radix)
{
	if (nullptr==str)
	{
		return nullptr;
	}

	uint32_t index=0;
	unsigned char ch=0;
	unsigned char buffer[32]={0};  /* space for NUMBER_OF_DIGITS + '\0' */

	if (value < 0 && radix == 10) 
	{
		*str++ = '-';
		value = -value;
	}

	index = 32;

	do 
	{
		ch = (unsigned char)('0' + (value % radix));
		if ( ch > '9') ch += 'a' - '9' - 1;

		buffer[ --index ] = ch;
		value /= radix;
	} while (value != 0);

	do 
	{
		*str++ = buffer[index++];
	} while ( index < 32 );

	*str = 0; 

	return str;
}

/**
 * @brief 用于把整数转换成字符串
 * @param value     为要转换为字符的数字
 * @param str       为转换后的指向字符串的指针
 * @param radix     为转换数字的进制数
 * @return 返回指向转换后的字符串指针
 * @note 编码格式 UTF-16
 */
char16_t *ositoa(int32_t value,char16_t *str,int32_t radix)
{
	if (nullptr==str)
	{
		return nullptr;
	}

	uint32_t index=0;
	char16_t ch=0;
	char16_t buffer[32]={0};  /* space for NUMBER_OF_DIGITS + '\0' */

	if (value < 0 && radix == 10) 
	{
		*str++ = u'-';
		value = -value;
	}

	index = 32;

	do 
	{
		ch = (char16_t)(u'0' + (value % radix));
		if ( ch > u'9') ch += u'a' - u'9' - 1;

		buffer[ --index ] = ch;
		value /= radix;
	} while (value != 0);

	do 
	{
		*str++ = buffer[index++];
	} while ( index < 32 );

	*str = 0; 

	return str;
}

/**
 * @brief 用于把整数转换成字符串
 * @param value     为要转换为字符的数字
 * @param str       为转换后的指向字符串的指针
 * @param radix     为转换数字的进制数
 * @return 返回指向转换后的字符串指针
 * @note 编码格式 UTF-32
 */
char32_t *ositoa(int32_t value,char32_t *str,int32_t radix)
{
	if (nullptr==str)
	{
		return nullptr;
	}

	uint32_t index=0;
	char32_t ch=0;
	char32_t buffer[32]={0};  /* space for NUMBER_OF_DIGITS + '\0' */

	if (value < 0 && radix == 10) 
	{
		*str++ = U'-';
		value = -value;
	}

	index = 32;

	do 
	{
		ch = (char32_t)(U'0' + (value % radix));
		if ( ch > U'9') ch += U'a' - U'9' - 1;

		buffer[ --index ] = ch;
		value /= radix;
	} while (value != 0);

	do 
	{
		*str++ = buffer[index++];
	} while ( index < 32 );

	*str = 0; 

	return str;
}

/**
 * @brief 把参数 str 所指向的字符串转换为一个浮点数（类型为 float 型）。
 * @param buf   要转换为浮点数的字符串
 * @return 函数返回转换后的双精度浮点数，如果没有执行有效的转换，则返回零（0.0）。
 * @note 编码格式 UTF-8
 */
float osatof(const char *buf)
{
	const char *ptr = buf;
	int32_t sign=0;           /* if '-', then negative, otherwise positive */
	float f = 0.0f;

	sign = 1;
	if (*ptr=='-')
	{
		sign = -1; 
		++ptr;
	}
	else if ('+'==*ptr)
	{
		++ptr;
	}

	bool afterdot = false;
	float fraction = 1.0f;
	while (*ptr) 
	{
		if (*ptr=='.') {
			afterdot = true;
			++ptr;
			continue;
		}

		if (!osisdigit(*ptr))
			break;

		int32_t digit = (*ptr)-'0';

		if (afterdot) 
		{
			fraction /= 10.0f;
			f += fraction*digit;
		}
		else 
		{
			f = f*10.0f+digit;
		}

		++ptr;
	}

	if (sign<0)
		return -f;
	else
		return f;
}

/**
 * @brief 把参数 str 所指向的字符串转换为一个浮点数（类型为 float 型）。
 * @param buf   要转换为浮点数的字符串
 * @return 函数返回转换后的双精度浮点数，如果没有执行有效的转换，则返回零（0.0）。
 * @note 编码格式 UTF-16
 */
float osatof(const char16_t *buf)
{
	const char16_t *ptr = buf;
	int32_t sign=0;           /* if '-', then negative, otherwise positive */
	float f = 0.0f;

	sign = 1;
	if (*ptr==u'-')
	{
		sign = -1; 
		++ptr;
	}
	else if (u'+'==*ptr)
	{
		++ptr;
	}

	bool afterdot = false;
	float fraction = 1.0f;
	while (*ptr) 
	{
		if (*ptr==u'.') {
			afterdot = true;
			++ptr;
			continue;
		}

		if (!osisdigit(*ptr))
			break;

		int32_t digit = (*ptr)-u'0';

		if (afterdot) 
		{
			fraction /= 10.0f;
			f += fraction*digit;
		}
		else 
		{
			f = f*10.0f+digit;
		}

		++ptr;
	}

	if (sign<0)
		return -f;
	else
		return f;
}

/**
 * @brief 把参数 str 所指向的字符串转换为一个浮点数（类型为 float 型）。
 * @param buf   要转换为浮点数的字符串
 * @return 函数返回转换后的双精度浮点数，如果没有执行有效的转换，则返回零（0.0）。
 * @note 编码格式 UTF-32
 */
float osatof(const char32_t *buf)
{
	const char32_t *ptr = buf;
	int32_t sign=0;           /* if '-', then negative, otherwise positive */
	float f = 0.0f;

	sign = 1;
	if (*ptr==U'-')
	{
		sign = -1; 
		++ptr;
	}
	else if (U'+'==*ptr)
	{
		++ptr;
	}

	bool afterdot = false;
	float fraction = 1.0f;
	while (*ptr) 
	{
		if (*ptr==U'.') {
			afterdot = true;
			++ptr;
			continue;
		}

		if (!osisdigit(*ptr))
			break;

		int32_t digit = (*ptr)-U'0';

		if (afterdot) 
		{
			fraction /= 10.0f;
			f += fraction*digit;
		}
		else 
		{
			f = f*10.0f+digit;
		}

		++ptr;
	}

	if (sign<0)
		return -f;
	else
		return f;
}

/**
 * @brief 把 src 所指向的字符串复制到 dest，最多复制 n 个字符。
 *        当 src 的长度小于 n 时，dest 的剩余部分将用空字节填充。
 * @param dest     指向用于存储复制内容的目标数组
 * @param src      要复制的字符串。
 * @param count    要从源中复制的字符数
 * @return 该函数返回最终复制的字符串。
 */
char *osstrncpy(char *dest,const char *src,int32_t count)
{
	char *saveddest = dest;

	while (*src && count > 0) {
		*dest++ = *src++;
		count--;
	}

	if (count <= 0)
	{
		// count小于或等于src字符串的长度
		//osprintk("warning:the length of the destination may be shorter than src!\n");
	}
	else
	{
		// count大于src字符串的长度
		*dest = 0;
	}

	return saveddest;
}

/**
 * @brief 把 src 所指向的字符串复制到 dest，最多复制 n 个字符。
 *        当 src 的长度小于 n 时，dest 的剩余部分将用空字节填充。
 * @param dest     指向用于存储复制内容的目标数组
 * @param src      要复制的字符串。
 * @param count    要从源中复制的字符数
 * @return 该函数返回最终复制的字符串。
 * @note 编码格式 UTF-16
 */
char16_t *osstrncpy(char16_t *dest,const char16_t *src,int32_t count)
{
	char16_t *saveddest = dest;

	while (*src && count > 0) {
		*dest++ = *src++;
		count--;
	}

	if (count <= 0)
	{
		// count小于或等于src字符串的长度
		//osprintk("warning:the length of the destination may be shorter than src!\n");
	}
	else
	{
		// count大于src字符串的长度
		*dest = 0;
	}

	return saveddest;
}

/**
 * @brief 把 src 所指向的字符串复制到 dest，最多复制 n 个字符。
 *        当 src 的长度小于 n 时，dest 的剩余部分将用空字节填充。
 * @param dest     指向用于存储复制内容的目标数组
 * @param src      要复制的字符串。
 * @param count    要从源中复制的字符数
 * @return 该函数返回最终复制的字符串。
 * @note 编码格式 UTF-32
 */
char32_t *osstrncpy(char32_t *dest,const char32_t *src,int32_t count)
{
	char32_t *saveddest = dest;

	while (*src && count > 0) {
		*dest++ = *src++;
		count--;
	}

	if (count <= 0)
	{
		// count小于或等于src字符串的长度
		//osprintk("warning:the length of the destination may be shorter than src!\n");
	}
	else
	{
		// count大于src字符串的长度
		*dest = 0;
	}

	return saveddest;
}

/**
 * @brief 把 src 所指向的字符串追加到 dest 所指向的字符串的结尾，直到 n 字符长度为止。
 * @param dest   指向目标数组，该数组包含了一个 C 字符串，且足够容纳追加后的字符串，包括额外的空字符。
 * @param src    要追加的字符串。
 * @param count  要追加的最大字符数。
 * @return 该函数返回一个指向最终的目标字符串 dest 的指针。
 */
char *osstrncat(char *dest,const char *src,int32_t count)
{
	char *saveddest=dest;

	int32_t len=osstrlen(dest);

	osstrncpy(dest+len,src,count);

	return saveddest;
}

/**
 * @brief 把 src 所指向的字符串追加到 dest 所指向的字符串的结尾，直到 n 字符长度为止。
 * @param dest   指向目标数组，该数组包含了一个 C 字符串，且足够容纳追加后的字符串，包括额外的空字符。
 * @param src    要追加的字符串。
 * @param count  要追加的最大字符数。
 * @return 该函数返回一个指向最终的目标字符串 dest 的指针。
 * @note 编码格式 UTF-16
 */
char16_t *osstrncat(char16_t *dest,const char16_t *src,int32_t count)
{
	char16_t *saveddest=dest;

	int32_t len=osstrlen(dest);

	osstrncpy(dest+len,src,count);

	return saveddest;
}

/**
 * @brief 把 src 所指向的字符串追加到 dest 所指向的字符串的结尾，直到 n 字符长度为止。
 * @param dest   指向目标数组，该数组包含了一个 C 字符串，且足够容纳追加后的字符串，包括额外的空字符。
 * @param src    要追加的字符串。
 * @param count  要追加的最大字符数。
 * @return 该函数返回一个指向最终的目标字符串 dest 的指针。
 * @note 编码格式 UTF-32
 */
char32_t *osstrncat(char32_t *dest,const char32_t *src,int32_t count)
{
	char32_t *saveddest=dest;

	int32_t len=osstrlen(dest);

	osstrncpy(dest+len,src,count);

	return saveddest;
}

/**
 * @brief 把 str1 和 str2 进行比较，最多比较前 n 个字节
 * @param s1      要进行比较的第一个字符串。
 * @param s2      要进行比较的第二个字符串。
 * @param count   要比较的最大字符数。
 * @return 如果返回值 < 0，则表示 s1 小于 s2。 
 * @return 如果返回值 > 0，则表示 s2 小于 s1。
 * @return 如果返回值 = 0，则表示 s1 等于 s2。
 * @note 编码格式 UTF-8
 */
int32_t osstrncmp(const char *s1,const char *s2,int32_t count)
{
	if (nullptr==s1&&nullptr==s2)
	{
		return 0;
	}
	else if (nullptr==s1)
	{
		return -1;
	}
	else if (nullptr==s2)
	{
		return 1;
	}

    if (count<=0)
    {
		return 0;
    }
	
	int32_t x=0;

    /*
    * This explicit guard needed to deal correctly with boundary
    * cases: strings shorter than 4 bytes and strings longer than
    * UINT_MAX-4 bytes .
    */
    if( count >= 4 )
    {
        /* unroll by four */
        for (; x < count-4; x+=4)
        {
            s1+=4;
            s2+=4;

            if (*(s1-4) == 0 || *(s1-4) != *(s2-4))
            {
                return(*(unsigned char *)(s1-4) - *(unsigned char *)(s2-4));
            }

            if (*(s1-3) == 0 || *(s1-3) != *(s2-3))
            {
                return(*(unsigned char *)(s1-3) - *(unsigned char *)(s2-3));
            }

            if (*(s1-2) == 0 || *(s1-2) != *(s2-2))
            {
                return(*(unsigned char *)(s1-2) - *(unsigned char *)(s2-2));
            }

            if (*(s1-1) == 0 || *(s1-1) != *(s2-1))
            {
                return(*(unsigned char *)(s1-1) - *(unsigned char *)(s2-1));
            }
        }
    }

    /* residual loop */
    for (; x < count; x++)
    {
        if (*s1 == 0 || *s1 != *s2)
        {
            return(*(unsigned char *)s1 - *(unsigned char *)s2);
        }
        s1+=1;
        s2+=1;
    }

    return 0;
}

/**
 * @brief 把 str1 和 str2 进行比较，最多比较前 n 个字节
 * @param s1      要进行比较的第一个字符串。
 * @param s2      要进行比较的第二个字符串。
 * @param count   要比较的最大字符数。
 * @return 如果返回值 < 0，则表示 s1 小于 s2。 
 * @return 如果返回值 > 0，则表示 s2 小于 s1。
 * @return 如果返回值 = 0，则表示 s1 等于 s2。
 * @note 编码格式 UTF-16
 */
int32_t osstrncmp(const char16_t *s1,const char16_t *s2, int32_t count)
{
	if (nullptr==s1 && nullptr==s2)
	{
		return 0;
	}
	else if (nullptr==s1)
	{
		return -1;
	}
	else if (nullptr==s2)
	{
		return 1;
	}

    if (count<=0)
    {
		return 0;
    }

	int32_t x=0;

    /*
    * This explicit guard needed to deal correctly with boundary
    * cases: strings shorter than 4 bytes and strings longer than
    * UINT_MAX-4 bytes .
    */
    if( count >= 4 )
    {
        /* unroll by four */
        for (; x < count-4; x+=4)
        {
            s1+=4;
            s2+=4;

            if (*(s1-4)==0||*(s1-4)!=*(s2-4))
            {
                return *(s1-4)-*(s2-4);
            }

            if (*(s1-3)==0||*(s1-3)!=*(s2-3))
            {
                return *(s1-3)-*(s2-3);
            }

            if (*(s1-2)==0||*(s1-2)!=*(s2-2))
            {
                return *(s1-2)-*(s2-2);
            }

            if (*(s1-1)==0||*(s1-1)!=*(s2-1))
            {
                return *(s1-1)-*(s2-1);
            }
        }
    }

    /* residual loop */
    for (; x < count; x++)
    {
        if (*s1 == 0 || *s1 != *s2)
        {
            return *s1-*s2;
        }
        s1+=1;
        s2+=1;
    }

    return 0;
}

/**
 * @brief 把 str1 和 str2 进行比较，最多比较前 n 个字节
 * @param s1      要进行比较的第一个字符串。
 * @param s2      要进行比较的第二个字符串。
 * @param count   要比较的最大字符数。
 * @return 如果返回值 < 0，则表示 s1 小于 s2。 
 * @return 如果返回值 > 0，则表示 s2 小于 s1。
 * @return 如果返回值 = 0，则表示 s1 等于 s2。
 * @note 编码格式 UTF-32
 */
int32_t osstrncmp(const char32_t *s1,const char32_t *s2, int32_t count)
{
	if (nullptr==s1 && nullptr==s2)
	{
		return 0;
	}
	else if (nullptr==s1)
	{
		return -1;
	}
	else if (nullptr==s2)
	{
		return 1;
	}

    if (count<=0)
    {
		return 0;
    }

	int32_t x=0;

    /*
    * This explicit guard needed to deal correctly with boundary
    * cases: strings shorter than 4 bytes and strings longer than
    * UINT_MAX-4 bytes .
    */
    if( count >= 4 )
    {
        /* unroll by four */
        for (; x < count-4; x+=4)
        {
            s1+=4;
            s2+=4;

            if (*(s1-4)==0||*(s1-4)!=*(s2-4))
            {
                return *(s1-4)-*(s2-4);
            }

            if (*(s1-3)==0||*(s1-3)!=*(s2-3))
            {
                return *(s1-3)-*(s2-3);
            }

            if (*(s1-2)==0||*(s1-2)!=*(s2-2))
            {
                return *(s1-2)-*(s2-2);
            }

            if (*(s1-1)==0||*(s1-1)!=*(s2-1))
            {
                return *(s1-1)-*(s2-1);
            }
        }
    }

    /* residual loop */
    for (; x < count; x++)
    {
        if (*s1 == 0 || *s1 != *s2)
        {
            return *s1-*s2;
        }
        s1+=1;
        s2+=1;
    }

    return 0;
}

/**
 * @brief 将字符串转为字符数组
 * @param str      字符串
 * @param dst      数组指针
 * @param count    数组能够容纳元素的数量
 * @return 返回数组中最终存储有效字符个数（不包括'\0'）
 */
static int32_t __string_to_array(const std::string &str,char *dst,const int32_t count)
{
	if (str.empty()||nullptr==dst||count<=1)
	{
		return 0;
	}
	const int32_t minCount = static_cast<int32_t>(str.length()) < (count-1) ? 
		static_cast<int32_t>(str.length()) : (count-1);
	for (int32_t i=0;i<minCount;++i)
	{
		dst[i]=str.at(i);
	}
	dst[minCount]='\0';
	return minCount;
}

/**
 * @brief 将字符串转为字符数组
 * @param str      字符串
 * @param dst      数组指针
 * @param count    数组能够容纳元素的数量
 * @return 返回数组中最终存储有效字符个数（不包括u'\0'）
 */
static int32_t __string_to_array(const std::u16string &str,char16_t *dst,const int32_t count)
{
	if (str.empty()||nullptr==dst||count<=1)
	{
		return 0;
	}
	const int32_t minCount = static_cast<int32_t>(str.length()) < (count-1) ? 
		static_cast<int32_t>(str.length()) : (count-1);
	for (int32_t i=0;i<minCount;++i)
	{
		dst[i]=str.at(i);
	}
	dst[minCount]=u'\0';
	return minCount;
}

/**
 * @brief 将字符串转为字符数组
 * @param str      字符串
 * @param dst      数组指针
 * @param count    数组能够容纳元素的数量
 * @return 返回数组中最终存储有效字符个数（不包括U'\0'）
 */
static int32_t __string_to_array(const std::u32string &str,char32_t *dst,const int32_t count)
{
	if (str.empty()||nullptr==dst||count<=1)
	{
		return 0;
	}
	const int32_t minCount = static_cast<int32_t>(str.length()) < (count-1) ? 
		static_cast<int32_t>(str.length()) : (count-1);
	for (int32_t i=0;i<minCount;++i)
	{
		dst[i]=str.at(i);
	}
	dst[minCount]=U'\0';
	return minCount;
}

/**
 * @brief 将指定字符串转为UTF-8编码
 * @param src    待转换字符串（编码: UTF-16）
 * @param dst    存储转换后的字符串（编码：UTF-8）
 * @param count  转换后字符串存储空间可容纳元素的数量
 * @return 返回转换后字符串长度（元素个数并非字节数）,如果转换后的长度大于等于存储空间尺寸（count）
 *         此时，函数将截断字符串，并将存储空间最后一位设置为'\0'
 */
int32_t osConvertToUTF8(const char16_t *src,char *dst,const int32_t count)
{
	if (nullptr==src||nullptr==dst||count<=1)
	{
		return 0;
	}
	try
    {
        std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> cvt;
		const std::string str=cvt.to_bytes(src);
		return __string_to_array(str,dst,count);
    }
    catch(const std::exception &)
    {
        return 0;
    }
}

/**
 * @brief 将指定字符串转为UTF-8编码
 * @param src    待转换字符串（编码: UTF-32）
 * @param dst    存储转换后的字符串（编码：UTF-8）
 * @param count  转换后字符串存储空间可容纳元素的数量
 * @return 返回转换后字符串长度（元素个数并非字节数）,如果转换后的长度大于等于存储空间尺寸（count）
 *         此时，函数将截断字符串，并将存储空间最后一位设置为'\0'
 */
int32_t osConvertToUTF8(const char32_t *src,char *dst,const int32_t count)
{
	if (nullptr==src||nullptr==dst||count<=1)
	{
		return 0;
	}
    try
    {
        std::wstring_convert<std::codecvt_utf8<char32_t>,char32_t> cvt;
        const std::string str=cvt.to_bytes(src);
		return __string_to_array(str,dst,count);
    }
    catch(const std::exception &)
    {
		return 0;
    }
}

/**
 * @brief 将指定字符串转为UTF-16编码
 * @param src    待转换字符串（编码: UTF-8）
 * @param dst    存储转换后的字符串（编码：UTF-16）
 * @param count  转换后字符串存储空间可容纳元素的数量
 * @return 返回转换后字符串长度（元素个数并非字节数）,如果转换后的长度大于等于存储空间尺寸（count）
 *         此时，函数将截断字符串，并将存储空间最后一位设置为'\0'
 */
int32_t osConvertToUTF16(const char *src,char16_t *dst,const int32_t count)
{
	if (nullptr==src||nullptr==dst||count<=1)
	{
		return 0;
	}
	try
	{
		std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> cvt;
		const std::u16string str=cvt.from_bytes(src);
		return __string_to_array(str,dst,count);
	}
	catch(const std::exception &)
	{
		return 0;
	}
}

/**
 * @brief 将指定字符串转为UTF-16编码
 * @param src    待转换字符串（编码: UTF-32）
 * @param dst    存储转换后的字符串（编码：UTF-16）
 * @param count  转换后字符串存储空间可容纳元素的数量
 * @return 返回转换后字符串长度（元素个数并非字节数）,如果转换后的长度大于等于存储空间尺寸（count）
 *         此时，函数将截断字符串，并将存储空间最后一位设置为'\0'
 */
int32_t osConvertToUTF16(const char32_t *src,char16_t *dst,const int32_t count)
{
	if (nullptr==src||nullptr==dst||count<=1)
	{
		return 0;
	}
    try
    {
        std::wstring_convert<std::codecvt_utf16<char32_t,0x10ffff,std::little_endian>,char32_t> cvt;
        std::string bytes=cvt.to_bytes(src);
		const std::u16string str(reinterpret_cast<const char16_t*>(bytes.c_str()),
			bytes.length()/sizeof(char16_t));
		return __string_to_array(str,dst,count);
    }
    catch(const std::exception &)
    {
		return 0;
    }
}

/**
 * @brief 将指定字符串转为UTF-32编码
 * @param src    待转换字符串（编码: UTF-8）
 * @param dst    存储转换后的字符串（编码：UTF-32）
 * @param count  转换后字符串存储空间可容纳元素的数量
 * @return 返回转换后字符串长度（元素个数并非字节数）,如果转换后的长度大于等于存储空间尺寸（count）
 *         此时，函数将截断字符串，并将存储空间最后一位设置为'\0'
 */
int32_t osConvertToUTF32(const char *src,char32_t *dst,const int32_t count)
{
	if (nullptr==src||nullptr==dst||count<=1)
	{
		return 0;
	}
    try
    {
        std::wstring_convert<std::codecvt_utf8<char32_t>,char32_t> cvt;
        const std::u32string str=cvt.from_bytes(src);
		return __string_to_array(str,dst,count);
    }
    catch(const std::exception &)
    {
		return 0;
    }	
}

/**
 * @brief 将指定字符串转为UTF-32编码
 * @param src    待转换字符串（编码: UTF-16）
 * @param dst    存储转换后的字符串（编码：UTF-32）
 * @param count  转换后字符串存储空间可容纳元素的数量
 * @return 返回转换后字符串长度（元素个数并非字节数）,如果转换后的长度大于等于存储空间尺寸（count）
 *         此时，函数将截断字符串，并将存储空间最后一位设置为'\0'
 */
int32_t osConvertToUTF32(const char16_t *src,char32_t *dst,const int32_t count)
{
	if (nullptr==src||nullptr==dst||count<=1)
	{
		return 0;
	}
	try
    {
		std::wstring_convert<std::codecvt_utf16<char32_t,0x10ffff,std::little_endian>,char32_t> cvt;
        const std::u32string str=cvt.from_bytes(reinterpret_cast<const char*>(src),
            reinterpret_cast<const char*>(src+osstrlen(src)));
		return __string_to_array(str,dst,count);
    }
    catch(const std::exception &)
    {
		return 0;
    }
}

/**
 * @brief   获取当前系统时间戳
 * @return  返回当前系统时间戳
 * @note    从1970-01-01 00:00:00 开始计时，到现在的毫秒数
 */
int64_t osGetTickCount()
{
	return std::chrono::duration_cast<std::chrono::milliseconds>(
		std::chrono::system_clock::now().time_since_epoch()).count();
}